package com.jeejio.img.picker

import android.content.Context
import android.database.Cursor
import android.os.Build
import android.provider.MediaStore
import android.text.TextUtils
import java.lang.reflect.Field
import java.util.*
import kotlin.collections.HashMap
import kotlin.collections.List
import kotlin.collections.Map
import kotlin.collections.MutableList
import kotlin.collections.set
import kotlin.collections.toTypedArray

/**
 * Author: JFangZ
 * Email:janezhang1901@163.com
 * Date: 2020/10/23 20:54
 * Description:
 */
object MediaPicker {
    private fun getProjection(clazz: Class<*>): Map<String, Field> {
        val map = HashMap<String, Field>()
        val fields = clazz.declaredFields

        for (field in fields) {
            if (!field.isAccessible) {
                field.isAccessible = true
            }
            val mediaColumn = field.getAnnotation(MediaColumn::class.java) ?: continue
            if (TextUtils.equals(mediaColumn.value, "duration") && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
                // API 29 以下没有 duration 字段
                continue
            }
            map[mediaColumn.value] = field
        }
        if (clazz.superclass != null && clazz.superclass != Any::class.java) {
            map.putAll(getProjection(clazz.superclass))
        }
        return map
    }

    fun getCount(context: Context, mediaCountStrategy: IMediaCountStrategy): Int {
        val cursor: Cursor = context.contentResolver.query(mediaCountStrategy.getUri(), arrayOf(MediaStore.Files.FileColumns._ID), mediaCountStrategy.getSelection(), mediaCountStrategy.getSelectionArgs(), null)
                ?: return 0
        val count = cursor.count
        cursor.close()
        return count
    }

    fun <T> getData(context: Context, mediaStrategy: IMediaStrategy<T>): List<T> {
        val map = getProjection(mediaStrategy.initBeanClass())
        val projection = map.keys.toTypedArray()
        val cursor = context.contentResolver.query(mediaStrategy.getUri(), projection, mediaStrategy.getSelection(), mediaStrategy.getSelectionArgs(), mediaStrategy.getOrder())
        val list: MutableList<T> = ArrayList()
        try {
            while (cursor != null && cursor.moveToNext()) {
                try {
                    val t: T = mediaStrategy.initBeanClass().newInstance()
                    for (entry in map.entries) {
                        // 根据类型,设置属性的值
                        when (entry.value.type) {
                            Int::class.java -> {
                                entry.value.set(t, cursor.getInt(cursor.getColumnIndex(entry.key)))
                            }
                            Long::class.java -> {
                                entry.value.set(t, cursor.getLong(cursor.getColumnIndex(entry.key)))
                            }
                            Float::class.java -> {
                                entry.value.set(t, cursor.getFloat(cursor.getColumnIndex(entry.key)))
                            }
                            Double::class.java -> {
                                entry.value.set(t, cursor.getDouble(cursor.getColumnIndex(entry.key)))
                            }
                            String::class.java -> {
                                entry.value.set(t, cursor.getString(cursor.getColumnIndex(entry.key)))
                            }
                            else -> {
                            }
                        }
                    }
                    list.add(t)
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        } finally {
            cursor?.close()
        }
        return list
    }
}
